'use strict';

var assert = require('assert');
var fs = require('fs');

var _ = require('lodash');
var unirest = require('unirest');
var Random = require('random-js');
var async = require('async');
var typeCheck = require('type-check').typeCheck;
var QQ = require('./model.js').QQ;


var webQQUrls = new Map([
    ['index', 'http://w.qq.com/login.html'],
	['qrcode', 'https://ssl.ptlogin2.qq.com/ptqrshow'],
    ['ptqrlogin', 'https://ssl.ptlogin2.qq.com/ptqrlogin'],
    ['login2', 'http://d.web2.qq.com/channel/login2'],
    ['poll', 'http://d.web2.qq.com/channel/poll2]'],
]);

var Session = function(qq) {
	this.active = false;
    this.qq = new QQ(qq);
	this.cookies = new Map();

    this.login();
};

/**
 * 将 res 中返回的 cookies obj 存
 */
Session.prototype.saveCookies = function(cookiesObj) {
	_.forEach(cookiesObj, (v, k) => {
		// 过滤生命周期等无关的值
		if (_.indexOf(["PATH", "DOMAIN", "EXPIRES"], k) !== -1) {
			return true;

		} else {
			this.cookies.set(k, v);
		}
	});
};

Session.prototype.isActive = function() {
	return this.active;
};

Session.prototype.login = function () {
    async.waterfall([
		// 获取真实的 login url，同时保存 cookie
        (callback) => {
            unirest.get(webQQUrls.get('index')).end((res) => {
                var loginUrlRegex = /\.src\ =\ "(.+?)"/;

                try {
                    var matchedLoginUrlArray = res.body.match(loginUrlRegex);

                    assert(matchedLoginUrlArray.length > 1, `matchedLoginUrlArray: ${matchedLoginUrlArray}`);
                    var loginUrl = res.body.match(loginUrlRegex)[1];

                } catch(e) {
                    console.error(e);
                    var loginUrl = '';
                }

                callback(null, loginUrl);
            });
        },
        // 获取 qrcode 图片以及保存 cookies
        (loginUrl, callback) => {
			assert(!_.isEmpty(loginUrl), `loginUrl: ${loginUrl}, 不合法`);

			unirest.get(loginUrl).end((res) => {
				var webQQInfo = {};
				this.saveCookies(res.cookies);

				var loginPageHtml = res.body;
				assert(!_.isEmpty(loginPageHtml));

				const appidRegex = /g_appid=encodeURIComponent\(\"(\d+)\"\)/;
				const signRegex = /g_login_sig=encodeURIComponent\(\"(.*?)\"\)/;
				const jsVerRegex = /g_pt_version=encodeURIComponent\(\"(\d+)\"\)/;
				const miBaoCssRegex = /g_mibao_css=encodeURIComponent\(\"(.*?)\"\)/;

				try {
					var appid = loginPageHtml.match(appidRegex)[1];
					var sign = loginPageHtml.match(signRegex)[1];
					var jsVer = loginPageHtml.match(jsVerRegex)[1];
					var miBaoCss = loginPageHtml.match(miBaoCssRegex)[1];

					webQQInfo = {
						appid: appid,
						sign: sign,
						jsVer: jsVer,
						miBaoCss: miBaoCss,
						loginUrl: loginUrl
					};

				} catch(e) {
					console.dir(e);
					webQQInfo = {};
				}

				callback(null, webQQInfo);
			});
        },
		// 获取 qr code
		(webQQInfo, callback) => {
			assert(!_.isEmpty(webQQInfo), `webQQInfo: ${webQQInfo}`);
			var that = this;

			var qrCodeUrl = `https://ssl.ptlogin2.qq.com/ptqrshow?appid=${webQQInfo.appId}&e=0&l=L&s=8&d=72&v=4`;
			var getQrCodeAt = (new Date()).getTime();

			unirest.get(qrCodeUrl).encoding("binary").end((res) => {
				this.saveCookies(res.cookies);
				res.setEncoding("binary");

				fs.writeFile(`./qrcode/${that.qq.number}.png`, res.body, {encoding: "binary"}, function(err) {
					if (err) {
						return callback(err);
					}

					console.log(`qq: ${that.qq.number}'s qrcode save success`);
					callback(null, webQQInfo, getQrCodeAt);
				});
			});
		},
		// 轮询用户登录情况
		(webQQInfo, getQrCodeAt, callback) => {
			var timeDelta = (new Date()).getTime() - getQrCodeAt;

			var url = `https://ssl.ptlogin2.qq.com/ptqrlogin?webqq_type=10&remember_uin=1&login2qq=1&aid=${webQQInfo.appid}&u1=http%3A%2F%2Fw.qq.com%2Fproxy.html%3Flogin2qq%3D1%26webqq_type%3D10&ptredirect=0&ptlang=2052&daid=164&from_ui=1&pttype=1&dumy=&fp=loginerroralert&action=0-0-${timeDelta}&mibao_css=${webQQInfo.miBaoCss}&t=undefined&g=1&js_type=0&js_ver=${webQQInfo.jsVer}&login_sig=${webQQInfo.sign}`;

			var cookiesArray = [];
			this.cookies.forEach(function(v, k) {
				if (_.indexOf(["pt_login_sig", "pt_clientip", "pt_serverip", "uikey", "qrsig"], k) === -1) {
					return true;

				} else {
					cookiesArray.push(`${k}=${v}`);
				}
			});
			var cookiesStr = cookiesArray.join("; ");

			setInterval(() => {
				unirest.get(url).header({
					"Cookie": cookiesStr

				}).end((res) => {
					var ret = res.body.split("'");
					this.saveCookies(res.cookies);

					switch(ret[1]) {
						case "65":
							// 尝试重新登录
							return callback("qrcode 失效");
							break;
						case "0":
							callback(null);
							console.dir("login ok");
							break;
						case "66":
							console.info("未失效，等待用户验证");
							break;
						case "67":
							console.info("验证中");
							break;
						default:
							console.error(res.body);
							callback("未知错误");
					}
				});
			}, 1000);

		}

    ], (err, results) => {
        if (err) {
            console.error(err);
        }

        console.info(results);
    });
};


exports.Session = Session;
